package org.abettor.nookinfo.wiki;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Random;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.abettor.nookinfo.AddressConstant;
import org.abettor.nookinfo.R;
import org.abettor.nookinfo.ads.YoumiManager;
import org.abettor.nookinfo.modal.WikiTerm;
import org.abettor.nookinfo.view.FileDialog;
import org.abettor.nookinfo.view.OnFileChosenListener;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.app.Activity;
import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

/**
 * 百科内容界面
 * @author shawn
 *
 */
public class WikiContent extends Activity
{
	private static final int REFRESHED = 1;//菜单更新已完成事件
	private static final int FAILED = 2;//菜单更新失败时间
	private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	public static final String WIKI_CONTENT_ID = "WIKI_CONTENT_ID";
	public static final String WIKI_CONTENT_NAME = "WIKI_CONTENT_NAME";
	private YoumiManager youmi = new YoumiManager(this);
	private int id;
	private WikiTerm term;
	private ProgressDialog progressDialog = null;//进度条对话框
	private Worker worker = null;//网络访问线程
	private Handler handler = new Handler()
	{
		@Override
		public void handleMessage(Message msg)
		{
			if(msg.what == REFRESHED)
			{
				//	清除图片
				LinearLayout layout = (LinearLayout) findViewById(R.id.wikiContentLayout);
				int count = layout.getChildCount();
				for(int i = count - 1; i > 0; i --)
				{
					layout.removeViewAt(i);
				}

				//	设定正文
				TextView title = (TextView) findViewById(R.id.wikiContentTitle);
				title.setText(term.name);
				TextView update = (TextView) findViewById(R.id.wikiContentUpdate);
				update.setText(sdf.format(term.update));
				TextView content = (TextView) findViewById(R.id.wikiContentText);
				content.setText(term.content.trim());

				//	设定保存百科文本的动作
				content.setLongClickable(true);
				content.setOnLongClickListener(new OnLongClickListener()
				{
					@Override
					public boolean onLongClick(View v)
					{
						//	设定保存百科文本的事件
						FileDialog dialog = new FileDialog(WikiContent.this, FileDialog.FileType.file);
						dialog.setTitle(R.string.wiki_content_save_text_title);
						dialog.setOnFileChosenListener(new OnFileChosenListener()
						{
							@Override
							public void onFileChosen(FileDialog dialog)
							{
								//	保存文本文件
								final File file = dialog.getFile();
								if(file == null)
								{
									return;
								}

								if(file.exists())
								{
									//	是否要覆盖文件
									Builder builder = new Builder(WikiContent.this);
									builder.setTitle(R.string.wiki_content_save_overwrite_title);
									builder.setMessage(R.string.wiki_content_save_overwrite_content);
									builder.setPositiveButton(R.string.wiki_content_save_overwrite_btn_ok, new DialogInterface.OnClickListener()
									{
										@Override
										public void onClick(DialogInterface dialoginterface, int i)
										{
											OutputStream os = null;
											try
											{
												file.delete();
												file.createNewFile();
												os = new FileOutputStream(file);
												String content = term.content.trim();
												os.write(content.getBytes("UTF-8"));
											}
											catch (Exception e)
											{
												Log.d(this.getClass().getName(), "", e);
											}
											finally
											{
												if(os != null)
												{
													try { os.close(); } catch (Exception e) { };
												}
											}
											dialoginterface.dismiss();
										}
									});
									builder.setNegativeButton(R.string.wiki_content_save_overwrite_btn_cancel, new DialogInterface.OnClickListener()
									{
										@Override
										public void onClick(DialogInterface dialog, int which)
										{
											dialog.dismiss();
										}
									});
									builder.show();
								}
								else
								{
									OutputStream os = null;
									try
									{
										file.createNewFile();
										os = new FileOutputStream(file);
										String content = term.content.trim();
										os.write(content.getBytes("UTF-8"));
									}
									catch (Exception e)
									{
										Log.d(this.getClass().getName(), "", e);
									}
									finally
									{
										if(os != null)
										{
											try { os.close(); } catch (Exception e) { };
										}
									}
								}
							}
						});
						dialog.show();
						return false;
					}
				});

				//	如果有的话，显示图片
				if(term.images != null && ! term.images.isEmpty())
				{
					for(Integer image : term.images)
					{
						InputStream is = null;
						try
						{
							String path = AddressConstant.WIKI_CONTENT_IMAGE_LOCAL.replace("ID", image + "");
							File file = new File(path);
							is = new FileInputStream(file);
							final Bitmap bitmap = BitmapFactory.decodeStream(is);
							LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
							params.gravity = 0x30 | 0x03;
							params.topMargin = 5;
							ImageView imageView = new ImageView(WikiContent.this);
							imageView.setLayoutParams(params);
							imageView.setImageBitmap(bitmap);
							layout.addView(imageView);

							//	设定保存图片的动作
							imageView.setLongClickable(true);
							imageView.setOnLongClickListener(new OnLongClickListener()
							{
								@Override
								public boolean onLongClick(View v)
								{
									//	设定保存百科图片的事件
									FileDialog dialog = new FileDialog(WikiContent.this, FileDialog.FileType.file);
									dialog.setTitle(R.string.wiki_content_save_image_title);
									dialog.setOnFileChosenListener(new OnFileChosenListener()
									{
										@Override
										public void onFileChosen(FileDialog dialog)
										{
											//	保存图片文件
											final File file = dialog.getFile();
											if(file == null)
											{
												return;
											}

											if(file.exists())
											{
												//	是否要覆盖文件
												Builder builder = new Builder(WikiContent.this);
												builder.setTitle(R.string.wiki_content_save_overwrite_title);
												builder.setMessage(R.string.wiki_content_save_overwrite_content);
												builder.setPositiveButton(R.string.wiki_content_save_overwrite_btn_ok, new DialogInterface.OnClickListener()
												{
													@Override
													public void onClick(DialogInterface dialoginterface, int i)
													{
														OutputStream os = null;
														try
														{
															file.delete();
															file.createNewFile();
															os = new FileOutputStream(file);
															bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
														}
														catch (Exception e)
														{
															Log.d(this.getClass().getName(), "", e);
														}
														finally
														{
															if(os != null)
															{
																try { os.close(); } catch (Exception e) { };
															}
														}
														dialoginterface.dismiss();
													}
												});
												builder.setNegativeButton(R.string.wiki_content_save_overwrite_btn_cancel, new DialogInterface.OnClickListener()
												{
													@Override
													public void onClick(DialogInterface dialog, int which)
													{
														dialog.dismiss();
													}
												});
												builder.show();
											}
											else
											{
												OutputStream os = null;
												try
												{
													file.createNewFile();
													os = new FileOutputStream(file);
													String content = term.content.trim();
													os.write(content.getBytes("UTF-8"));
												}
												catch (Exception e)
												{
													Log.d(this.getClass().getName(), "", e);
												}
												finally
												{
													if(os != null)
													{
														try { os.close(); } catch (Exception e) { };
													}
												}
											}
										}
									});
									dialog.show();
									return false;
								}
							});
						}
						catch (Exception e)
						{
							Log.d(this.getClass().getName(), "", e);
						}
						finally
						{
							if(is != null)
							{
								try { is.close(); } catch (Exception e) { };
							}
						}
					}
				}

				ScrollView scroll = (ScrollView) findViewById(R.id.wikiContentScroll);
				scroll.scrollTo(0, 0);

				//	按照一定的概率显示广告
				Random rand = new Random(System.currentTimeMillis());
				int val = rand.nextInt(99);
				if(val < 20)
				{
					youmi.showYoumi(YoumiManager.Position.middle, Color.WHITE, Color.BLACK, 0xAA);
				}
			}
			else if(msg.what == FAILED)
			{
				Builder builder = new Builder(WikiContent.this);
				builder.setTitle(R.string.wiki_content_fail_title);
				builder.setMessage(R.string.wiki_content_fail_content);
				builder.setPositiveButton(R.string.wiki_content_fail_btn_ok, new DialogInterface.OnClickListener()
				{
					@Override
					public void onClick(DialogInterface dialoginterface, int i)
					{
						dialoginterface.dismiss();
					}
				});
				builder.show();
			}
			super.handleMessage(msg);
		}
	};

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.wiki_content);
		Intent intent = getIntent();
		Bundle extras = intent.getExtras();
		id = extras.getInt(WIKI_CONTENT_ID);
		String name = extras.getString(WIKI_CONTENT_NAME);
		String label = getString(R.string.wiki_content_label);
		label = label.replace("REPL", name);
		setTitle(label);
		onRefreshClicked(null);
	}

	/**
	 * “刷新”按钮事件方法
	 * @param v
	 */
	public void onRefreshClicked(View v)
	{
		removeImages();
		worker = new Worker();
		worker.start();
		progressDialog = new ProgressDialog(this);
		progressDialog.setCancelable(true);
		progressDialog.setTitle(R.string.wiki_content_progress_title);
		progressDialog.setMessage(getText(R.string.wiki_content_progress_content));
		progressDialog.setButton(getText(R.string.wiki_content_progress_btn_cancel), new DialogInterface.OnClickListener()
		{
			@Override
			public void onClick(DialogInterface dialoginterface, int i)
			{
				worker.kill();
			}
		});
		progressDialog.show();
		synchronized (worker)
		{
			worker.notify();
		}
	}

	/**
	 * “查询”按钮事件方法
	 * @param v
	 */
	public void onSearchClicked(View v)
	{
		//	显示搜索界面
		Intent search = new Intent();
		search.setClass(this, WikiSearch.class);
		startActivity(search);
	}

	/**
	 * 重载返回按钮事件
	 */
	@Override
	public void onBackPressed()
	{
		onRetrunClicked(null);
	}

	/**
	 * “返回”按钮事件方法
	 * @param v
	 */
	public void onRetrunClicked(View v)
	{
		removeImages();
		finish();
	}

	//	删除图片
	private void removeImages()
	{
		if(term == null || term.images == null)
		{
			return;
		}

		for(Integer id : term.images)
		{
			String path = AddressConstant.WIKI_CONTENT_IMAGE_LOCAL.replace("ID", id + "");
			File file = new File(path);
			if(file.exists())
			{
				file.delete();
			}
		}
	}

	/**
	 * 读取百科内容的工作线程类
	 * @author abettor
	 *
	 */
	private class Worker extends Thread
	{
		//	线程是否为意外退出的标记
		private boolean cancel = false;

		/**
		 * 强制杀死工作者线程
		 */
		public void kill()
		{
			cancel = true;
			this.interrupt();
		}

		@Override
		public void run()
		{
			try
			{
				//	等待对话框创建完成
				synchronized (this)
				{
					wait();
				}

				//	此处访问网络并获取列表
				term = fetchWikiContent();

				//	关闭进度对话框并通知界面更新
				progressDialog.dismiss();
				if(! cancel)
				{
					//	在非意外中断情况下才更新界面
					Message msg = new Message();
					msg.what = REFRESHED;
					handler.sendMessage(msg);
				}
				else
				{
					//	意外中断的情况下，显示错误对话框
					Message msg = new Message();
					msg.what = FAILED;
					handler.sendMessage(msg);
				}
			}
			catch (Exception e)
			{
				//	清除列表
				try { progressDialog.dismiss(); } catch (Exception ex) { };
				//	意外中断的情况下，显示错误对话框
				Message msg = new Message();
				msg.what = FAILED;
				handler.sendMessage(msg);
				Log.d(this.getClass().getName(), "", e);
			}
		}

		//	读取百科内容信息
		private WikiTerm fetchWikiContent() throws Exception
		{
			WikiTerm term = new WikiTerm();
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			String url = AddressConstant.WIKI_CONTENT.replace("ID", id + "");
			Document doc = db.parse(url);
			NodeList nodes = doc.getElementsByTagName("term").item(0).getChildNodes();
			int count = nodes.getLength();
			for(int i = 0; i < count; i ++)
			{
				Node termNode = nodes.item(i);
				String nodeName = termNode.getNodeName();
				if("id".equals(nodeName))
				{
					String id = termNode.getTextContent();
					term.id = Integer.valueOf(id);
				}
				else if("name".equals(nodeName))
				{
					term.name = termNode.getTextContent();
				}
				else if("update".equals(nodeName))
				{
					String update = termNode.getTextContent();
					term.update = sdf.parse(update);
				}
				else if("content".equals(nodeName))
				{
					term.content = "";
					NodeList summaryNodes = termNode.getChildNodes();
					int size = summaryNodes.getLength();
					for(int k = 0; k < size; k ++)
					{
						Node summary = summaryNodes.item(k);
						if(summary instanceof CDATASection)
						{
							CDATASection cdata = (CDATASection) summary;
							term.content = cdata.getData();
							break;
						}
					}
				}
			}

			nodes = doc.getElementsByTagName("image");
			if(nodes != null && nodes.getLength() > 0)
			{
				term.images = new ArrayList<Integer>();
				int size = nodes.getLength();
				for(int i = 0; i < size; i ++)
				{
					Node node = nodes.item(i);
					String value = node.getTextContent();
					int imageId = Integer.parseInt(value);
					term.images.add(imageId);
					saveImage(imageId);
				}
			}

			return term;
		}

		//	保存图片文件到本地
		private void saveImage(int imageId) throws Exception
		{
			String path = AddressConstant.WIKI_CONTENT_IMAGE_LOCAL.replace("ID", imageId + "");
			File file = new File(path);
			if(! file.exists())
			{
				String url = AddressConstant.WIKI_CONTENT_IMAGE.replace("ID", imageId + "");
				URL theUrl = new URL(url);
				InputStream is = theUrl.openStream();
				Bitmap bitmap = BitmapFactory.decodeStream(is);
				is.close();

				File dir = file.getParentFile();
				if(! dir.exists())
				{
					dir.mkdirs();
				}

				file.createNewFile();
				FileOutputStream os = new FileOutputStream(file);
				bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
				os.close();
			}
		}
	}
}
